/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tt.VorlesungenService;

import java.io.*;
import java.util.Collection;
import java.util.Iterator;
import tt.model.*;
import net.fortuna.ical4j.data.*;
import net.fortuna.ical4j.model.*;
import net.fortuna.ical4j.util.UidGenerator;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.component.VEvent;
import java.util.GregorianCalendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.property.*;
import net.fortuna.ical4j.model.component.*;

/**
 *
 * @author johannes
 */
public class IcsCalendar {

    DateTime von;
    DateTime bis;
    java.util.Calendar calendarVon = java.util.Calendar.getInstance();
    java.util.Calendar calendarBis = java.util.Calendar.getInstance();
    VTimeZone tz;
    java.util.Calendar jvon;
    java.util.Calendar jbis;

    public IcsCalendar(General GeneralSettings) {

//TimeZoneRegistry registry = new TimeZoneRegistryImpl("zoneinfo-outlook/");
        TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
        TimeZone timezone = registry.getTimeZone("Europe/Berlin");
        tz = timezone.getVTimeZone();

        calendarVon = new GregorianCalendar();
        calendarBis = new GregorianCalendar();
        calendarVon.setTimeZone(timezone);
        calendarBis.setTimeZone(timezone);

        //java.util.TimeZone tz = TimeZone.getDefault();
        jvon = java.util.Calendar.getInstance(timezone);
        jvon.setTime(GeneralSettings.getSemesterstart());

        jbis = java.util.Calendar.getInstance(timezone);
        jbis.setTime(GeneralSettings.getExamstart());


        calendarVon.set(java.util.Calendar.MONTH, jvon.get(java.util.Calendar.MONTH));
        calendarVon.set(java.util.Calendar.DAY_OF_MONTH, jvon.get(java.util.Calendar.DAY_OF_MONTH));
        calendarVon.set(java.util.Calendar.YEAR, jvon.get(java.util.Calendar.YEAR));

        calendarBis.set(java.util.Calendar.MONTH, jbis.get(java.util.Calendar.MONTH));
        calendarBis.set(java.util.Calendar.DAY_OF_MONTH, jbis.get(java.util.Calendar.DAY_OF_MONTH));
        calendarBis.set(java.util.Calendar.YEAR, jbis.get(java.util.Calendar.YEAR));

        bis = new DateTime(calendarBis.getTime());
        von = new DateTime(calendarVon.getTime());

    }//endmethod

    public String createCalendar(Courseschedule mySchedule) {
        String rueckgabe = " ";

        Collection<Lecturedate> myLectureDates = mySchedule.getLecturedateCollection();


        //CalendarKlasse erstellt <<<<<<
        Calendar calendar = new Calendar();
        calendar.getProperties().add(new ProdId("-//Ben Fortuna//iCal4j 1.0.3//DE"));
        calendar.getProperties().add(Version.VERSION_2_0);
        calendar.getProperties().add(CalScale.GREGORIAN);

        //Termin erstellen
        Lecturedate currentLecturedate = null;
        VEvent termin = null;


        for (Iterator<Lecturedate> it = myLectureDates.iterator(); it.hasNext();) {
            currentLecturedate = it.next();
            Date datum = new Date(currentLecturedate.getStarttime());
            try {
                UidGenerator ug = new UidGenerator("1");
                termin.getProperties().add(ug.generateUid());
            } catch (Exception e) {
                System.out.println("UID Generator exception: " + e);
            }

            termin = new VEvent(new Date(currentLecturedate.getStarttime()), currentLecturedate.getLecture().getLecname());

            calendar.getComponents().add(termin);

            //Calendar durch Stream abspeichern
            try {
                FileOutputStream fout = new FileOutputStream("C:/Users/johannes/Desktop/kalendar.ics");

                CalendarOutputter outputter = new CalendarOutputter();
                outputter.output(calendar, fout);
            }//endtry
            catch (Exception e) {
                System.out.println("Exeption 2: " + e);
            }

//            rueckgabe += "<b>" + currentLecturedate.getLecture().getLecname() + "</b><br>";
//            rueckgabe += currentLecturedate.getDay() + ", " + currentLecturedate.getStarttime() + "<br>";

        }//endfor        

        return rueckgabe;
    }//endmethod

    public String createIcsFile(Courseschedule mySchedule) {
        String rueckgabe = null;
        Collection<Lecturedate> myLectureDates = mySchedule.getLecturedateCollection();



        //CalendarKlasse erstellt <<<<<<
        Calendar calendar = new Calendar();
        calendar.getProperties().add(new ProdId("-//Ben Fortuna//iCal4j 1.0.3//DE"));
        calendar.getProperties().add(Version.VERSION_2_0);
        calendar.getProperties().add(CalScale.GREGORIAN);
        calendar.getComponents().add(tz);

        //Termin initialisieren
        Lecturedate currentLecturedate;
        VEvent termin;
        Location ort;
        long days = daysBetween(bis, von);
        UidGenerator ug = null;
        try {
            ug = new UidGenerator("300");
        } catch (Exception e) {
            Logger.getLogger(IcsCalendar.class.getName()).log(Level.INFO, "message");
            Logger.getLogger(IcsCalendar.class.getName()).log(Level.WARNING, e.toString());
        }


        for (Iterator<Lecturedate> it = myLectureDates.iterator(); it.hasNext();) {
            currentLecturedate = it.next();

            //Terminzeit erstellen + Uhrzeit einfügen
            java.util.Calendar copyof_calendarVon = calendarVon;
            copyof_calendarVon.set(java.util.Calendar.DAY_OF_MONTH, jvon.get(java.util.Calendar.DAY_OF_MONTH));

            //String to Integer --> erster Tag Vorlesung
            int tempdayCurLect;
            int tempdaySemStart;
            if (currentLecturedate.getDay().startsWith("Mon")) {
                tempdayCurLect = 1;
            } else if (currentLecturedate.getDay().startsWith("Die")) {
                tempdayCurLect = 2;
            } else if (currentLecturedate.getDay().startsWith("Mit")) {
                tempdayCurLect = 3;
            } else if (currentLecturedate.getDay().startsWith("Don")) {
                tempdayCurLect = 4;
            } else if (currentLecturedate.getDay().startsWith("Fre")) {
                tempdayCurLect = 5;
            } else if (currentLecturedate.getDay().startsWith("Sam")) {
                tempdayCurLect = 6;
            } else {
                tempdayCurLect = 7;
            }//endif


            //Konvertierung Wochentag --> US-Format nach D-Format
            if (copyof_calendarVon.get(java.util.Calendar.DAY_OF_WEEK) == 1) {
                tempdaySemStart = 7;
            } else if (copyof_calendarVon.get(java.util.Calendar.DAY_OF_WEEK) == 2) {
                tempdaySemStart = 1;
            } else if (copyof_calendarVon.get(java.util.Calendar.DAY_OF_WEEK) == 3) {
                tempdaySemStart = 2;
            } else if (copyof_calendarVon.get(java.util.Calendar.DAY_OF_WEEK) == 4) {
                tempdaySemStart = 3;
            } else if (copyof_calendarVon.get(java.util.Calendar.DAY_OF_WEEK) == 5) {
                tempdaySemStart = 4;
            } else if (copyof_calendarVon.get(java.util.Calendar.DAY_OF_WEEK) == 6) {
                tempdaySemStart = 5;
            } else {
                tempdaySemStart = 6;
            }//endif


            //Verschiebung des ersten Semesterstarttages wenn nötig
            if (tempdaySemStart != tempdayCurLect) {
                if (tempdayCurLect > tempdaySemStart) {
                    int adddays = tempdayCurLect - tempdaySemStart;
                    copyof_calendarVon.add(java.util.Calendar.DAY_OF_MONTH, adddays);
                } else if ((tempdayCurLect < tempdaySemStart)) {
                    int subdays = tempdaySemStart - tempdayCurLect;
                    copyof_calendarVon.add(java.util.Calendar.DAY_OF_MONTH, -subdays);
                    copyof_calendarVon.add(java.util.Calendar.DAY_OF_MONTH, 7);
                }//endif
            }//endif


            copyof_calendarVon.set(java.util.Calendar.HOUR_OF_DAY, currentLecturedate.getHourofStarttime());
            copyof_calendarVon.set(java.util.Calendar.MINUTE, currentLecturedate.getMinuteofStarttime());
            copyof_calendarVon.set(java.util.Calendar.SECOND, 00);

            DateTime calVon = new DateTime(copyof_calendarVon.getTime());
            Dur dur = new Dur(0, 01, 30, 00);
            termin = new VEvent(calVon, dur, currentLecturedate.getLecture().getLecname());
            ort = new Location(currentLecturedate.getRoom());
            termin.getProperties().add(ort);
            termin.getProperties().add(tz.getTimeZoneId());

            //Wiederholung festlegen
            Recur recur = new Recur(Recur.WEEKLY, lessonWeeks(days));

            if ((currentLecturedate.getDay()).compareToIgnoreCase("Montag") == 0) {
                recur.getDayList().add(WeekDay.MO);
            } else if ((currentLecturedate.getDay()).compareToIgnoreCase("Dienstag") == 0) {
                recur.getDayList().add(WeekDay.TU);
            } else if ((currentLecturedate.getDay()).compareToIgnoreCase("Mittwoch") == 0) {
                recur.getDayList().add(WeekDay.WE);
            } else if ((currentLecturedate.getDay()).compareToIgnoreCase("Donnerstag") == 0) {
                recur.getDayList().add(WeekDay.TH);
            } else if ((currentLecturedate.getDay()).compareToIgnoreCase("Freitag") == 0) {
                recur.getDayList().add(WeekDay.FR);
            } else if ((currentLecturedate.getDay()).compareToIgnoreCase("Samstag") == 0) {
                recur.getDayList().add(WeekDay.SA);
            } else if ((currentLecturedate.getDay()).compareToIgnoreCase("Sonntag") == 0) {
                recur.getDayList().add(WeekDay.SU);
            }
            RRule rrule = new RRule(recur);
            termin.getProperties().add(rrule);

            try {
                termin.getProperties().add(ug.generateUid());
            } catch (Exception e) {
                System.out.println(e);
            }//endtry

            calendar.getComponents().add(termin);
            rueckgabe = calendar.toString();


        }//endfor
        return rueckgabe;

    }//endmethod writeics

    public String createExamIcsFile(Collection myLectures) {
        String rueckgabe = null;


        //CalendarKlasse erstellt <<<<<<
        Calendar calendar = new Calendar();
        calendar.getProperties().add(new ProdId("-//Ben Fortuna//iCal4j 1.0.3//DE"));
        calendar.getProperties().add(Version.VERSION_2_0);
        calendar.getProperties().add(CalScale.GREGORIAN);
        calendar.getComponents().add(tz);

        //Termin initialisieren
        Lecture currentLecture;
        VEvent termin = null;
        Location ort;
        long days = daysBetween(bis, von);
        UidGenerator ug = null;
        try {
            ug = new UidGenerator("300");
        } catch (Exception e) {
            Logger.getLogger(IcsCalendar.class.getName()).log(Level.INFO, "message");
            Logger.getLogger(IcsCalendar.class.getName()).log(Level.WARNING, e.toString());
        }

        for (Iterator<Lecture> it = myLectures.iterator(); it.hasNext();) {
            currentLecture = it.next();

            if (currentLecture.getExam() == null) {
                //Kein Examen verknüpfen
            } else {
                //Terminzeit erstellen + Uhrzeit einfügen
                java.util.Calendar copyof_calendarVon = calendarVon;

                DateTime helpExamDate = new DateTime(currentLecture.getExam().getExamdate());
                DateTime helpExamTime = new DateTime(currentLecture.getExam().getStartofexam());

                String dateDay = helpExamDate.toString();
                String dateMonth = helpExamDate.toString();
                String dateYear = helpExamDate.toString();
                dateDay = dateDay.substring(6, 8);
                dateMonth = dateMonth.substring(4, 6);
                dateYear = dateYear.substring(0, 4);

                String dateHour = helpExamTime.toString();
                String dateMinute = helpExamTime.toString();
                dateHour = dateHour.substring(9, 11);
                dateMinute = dateMinute.substring(11, 13);

                copyof_calendarVon.set(java.util.Calendar.YEAR, Integer.parseInt(dateYear));
                copyof_calendarVon.set(java.util.Calendar.MONTH, (Integer.parseInt(dateMonth)) - 1);
                copyof_calendarVon.set(java.util.Calendar.DAY_OF_MONTH, Integer.parseInt(dateDay));
                copyof_calendarVon.set(java.util.Calendar.HOUR_OF_DAY, Integer.parseInt(dateHour));
                copyof_calendarVon.set(java.util.Calendar.MINUTE, Integer.parseInt(dateMinute));

                DateTime calVon = new DateTime(copyof_calendarVon.getTime());
                Dur dur = new Dur(0, 01, 30, 00);
                termin = new VEvent(calVon, dur, currentLecture.getLecname());
                ort = new Location(currentLecture.getExam().getExamroom());

                termin.getProperties().add(ort);
                termin.getProperties().add(tz.getTimeZoneId());



                try {
                    termin.getProperties().add(ug.generateUid());
                } catch (Exception e) {
                    System.out.println(e);
                }//endtry

                calendar.getComponents().add(termin);
                rueckgabe = calendar.toString();

            }//end if else
        }//endfor
        return rueckgabe;

    }//endmethod writeics

    public static long daysBetween(Date max, Date min) {
        return (max.getTime() - min.getTime()) / 86400000;
    }//endmethod

    public static int lessonWeeks(long daysbetween) {
        int weeks;
        int rest = (int) daysbetween % 7;
        daysbetween = daysbetween - rest;
        weeks = (int) daysbetween / 7;
        return weeks + 1;
    }//endmethod
}//endclass
